package logic

import (
	"context"
	"errors"
	"fmt"
	"github.com/google/uuid"
	"lucky/cache"
	"lucky/models"
	"strings"
	"time"

	"lucky/luckyrpc/internal/svc"
	"lucky/luckyrpc/luckyrpc"

	"github.com/zeromicro/go-zero/core/logx"
)

type CreatOrderLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewCreatOrderLogic(ctx context.Context, svcCtx *svc.ServiceContext) *CreatOrderLogic {
	return &CreatOrderLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *CreatOrderLogic) CreatOrder(in *luckyrpc.CreatOrderRequest) (*luckyrpc.CreatOrderResponse, error) {
	// todo: add your logic here and delete this line

	var (
		totalAmount float64
		orderItems  []models.OrderItem
	)

	OrderSn := GetOrderSn(in.UserId)

	for _, item := range in.Item {
		key := fmt.Sprintf("product_stock:%d", item.ProductId)

		var product models.Product
		err := models.DB.Debug().Where("id = ?", item.ProductId).First(&product).Error
		if err != nil {
			return nil, fmt.Errorf("当前商品还未上架，尽情期待")
		}
		fmt.Println(product)

		if cache.GetStock(int(item.ProductId)) < item.Quantity {
			return nil, errors.New(fmt.Sprintf("商品Id%d,库存不足", item.ProductId))
		}

		pipe := cache.Rdb.TxPipeline()
		for i := 0; i < int(item.Quantity); i++ {
			pipe.RPop(l.ctx, key)
		}
		_, err = pipe.Exec(l.ctx)
		if err != nil {
			return nil, errors.New(fmt.Sprintf("商品Id%d库存扣减失败%v", item.ProductId, err))
		}

		subtotal := product.Price * float64(item.Quantity)
		totalAmount += subtotal

		orderItem := models.OrderItem{
			OrderSn:      OrderSn,
			ProductId:    product.ID,
			ProductName:  product.Name,
			ProductPrice: product.Price,
			ProductImage: product.ImageUrl,
			Quantity:     int(item.Quantity),
			SubTotal:     subtotal,
		}
		fmt.Println(orderItem)
		orderItems = append(orderItems, orderItem)

	}

	begin := models.DB.Debug().Begin()

	order := models.Order{
		UserId:  in.UserId,
		OrderSn: OrderSn,
		Total:   totalAmount,
		Status:  0,
		PayType: 0,
		Address: in.Address,
	}
	fmt.Println(orderItems)
	err := begin.Create(&order).Error
	if err != nil {
		begin.Rollback()
		return nil, err
	}
	err = begin.Create(&orderItems).Error
	if err != nil {
		begin.Rollback()
		return nil, err
	}
	begin.Commit()

	//url, err := pkg.AliPay(OrderSn, totalAmount)
	//if err != nil {
	//	return nil, err
	//}

	return &luckyrpc.CreatOrderResponse{
		TotalAmount: float32(totalAmount),
		OrderSn:     OrderSn,
		//Url:         url,
	}, nil
}
func GetOrderSn(userId int64) string {
	NowTime := time.Now().Format("060102150405")
	User := fmt.Sprintf("%04d", userId%10000)
	str := uuid.New().String()
	uuidStr := strings.Replace(str, "-", "", -1)
	uuidStr = uuidStr[:4]
	sn := fmt.Sprintf("%s%s%s", NowTime, User, uuidStr)
	return sn
}
